#pragma once

#include "../../Libs/headers.default.h"
#include "../../Libs/headers.classification.h"

using namespace loirey;

namespace nw_rbm
{
	class CConnectionManager
	{
	public:
		virtual CConnectionManager* myClone() = 0;
		virtual void myRelease()
		{
		}
		virtual ~CConnectionManager();
	public:
		virtual int GetAmountConnection(int UnitHandle) const = 0;
		virtual int GetUnitConnectionList(
			int UnitHandle,
			CSimpleTypeArray<int>& vTargetHandle,
			CSimpleTypeArray<int>& vEdgeHandle) const = 0;
		virtual bool ClearAllConnections() = 0;
		virtual bool ClearUnitConnections(int UnitHandle) = 0;
		virtual bool NewConnection(int UnitHandle, int TargetHandle, int EdgeHandle) = 0;
	public:
		static CConnectionManager* myClone(
			CConnectionManager* pPrototype);
		static void myRelease(
			CConnectionManager* pInstance);
		static int GetAmountConnection(
			const CConnectionManager* qConnectionManager,
			int UnitHandle);
		static int GetUnitConnectionList(
			const CConnectionManager* qConnectionManager,
			int UnitHandle,
			CSimpleTypeArray<int>& vTargetHandle,
			CSimpleTypeArray<int>& vEdgeHandle);
		static bool ClearAllConnections(
			CConnectionManager* pConnectionManager);
		static bool ClearUnitConnections(
			CConnectionManager* pConnectionManager,
			int UnitHandle);
		static bool NewConnection(
			CConnectionManager* pConnectionManager,
			int UnitHandle, int TargetHandle, int EdgeHandle);
	};

	class CUnitConnections
	{
	public:
		int Dimension;
		CSimpleTypeArray<int> vTargetHandle;
		CSimpleTypeArray<int> vEdgeHandle;

	public:
		CUnitConnections();
		virtual void Clear();
		virtual void DeepClear();
		virtual void NewConnection(int TargetHandle, int EdgeHandle);
	};

	class CConnectionManager_Basic : public CConnectionManager
	{
	public:
		typedef map<int, CUnitConnections> CUnitConnectionDictionary;

	public:
		CUnitConnectionDictionary UnitConnectionDictionary;

	public:
		CConnectionManager_Basic();
		virtual CConnectionManager* myClone();
		virtual void myRelease();
	public:
		virtual int GetAmountConnection(int UnitHandle) const;
		virtual int GetUnitConnectionList(
			int UnitHandle,
			CSimpleTypeArray<int>& vTargetHandle,
			CSimpleTypeArray<int>& vEdgeHandle) const;
		virtual bool ClearAllConnections();
		virtual bool ClearUnitConnections(int UnitHandle);
		virtual bool NewConnection(int UnitHandle, int TargetHandle, int EdgeHandle);
	};

	template<typename T>
	class CConnectionManager_Proxy : public CConnectionManager
	{
	public:
		T* pExecutor;
	public:
		int (T::*pGetAmountConnection)(
			int UnitHandle) const;
		int (T::*pGetUnitConnectionList)(
			int UnitHandle,
			CSimpleTypeArray<int>& vTargetHandle,
			CSimpleTypeArray<int>& vEdgeHandle) const;
		bool (T::*pClearAllConnections)(
			);
		bool (T::*pClearUnitConnections)(
			int UnitHandle);
		bool (T::*pNewConnection)(
			int UnitHandle, int TargetHandle, int EdgeHandle);

	public:
		CConnectionManager_Proxy()
		{
			pExecutor = NULL;
			pGetAmountConnection = NULL;
			pGetUnitConnectionList = NULL;
			pClearUnitConnections = NULL;
			pNewConnection = NULL;
		}
		virtual CConnectionManager* myClone()
		{
			return new CConnectionManager_Proxy<T>(*this);
		}
		virtual void myRelease()
		{
			pGetAmountConnection = NULL;
			pGetUnitConnectionList = NULL;
			pClearAllConnections = NULL;
			pClearUnitConnections = NULL;
			pNewConnection = NULL;
		}
		virtual int GetAmountConnection(
			int UnitHandle) const
		{
			if (pExecutor==NULL || pGetAmountConnection==NULL) return 0;
			return (pExecutor->*pGetAmountConnection)(
				UnitHandle);
		}
		virtual int GetUnitConnectionList(
			int UnitHandle,
			CSimpleTypeArray<int>& vTargetHandle,
			CSimpleTypeArray<int>& vEdgeHandle) const
		{
			if (pExecutor==NULL || pGetUnitConnectionList==NULL) return 0;
			return (pExecutor->*pGetUnitConnectionList)(
				UnitHandle, vTargetHandle, vEdgeHandle);
		}
		virtual bool ClearAllConnections()
		{
			if (pExecutor==NULL || pClearAllConnections==NULL) return false;
			return (pExecutor->*pClearAllConnections)();
		}
		virtual bool ClearUnitConnections(int UnitHandle)
		{
			if (pExecutor==NULL || pClearUnitConnections==NULL) return false;
			return (pExecutor->*pClearUnitConnections)(UnitHandle);
		}
		virtual bool NewConnection(int UnitHandle, int TargetHandle, int EdgeHandle)
		{
			if (pExecutor==NULL || pNewConnection==NULL) return false;
			return (pExecutor->*pNewConnection)(UnitHandle, TargetHandle, EdgeHandle);
		}
	};

}

